package com.rbac.application.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.crypto.digest.BCrypt;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.rbac.application.service.AuthService;
import com.rbac.application.service.MenuService;
import com.rbac.application.service.UserService;
import com.rbac.common.enums.BusinessErrorCode;
import com.rbac.common.exception.BusinessException;
import com.rbac.domain.dto.request.LoginRequest;
import com.rbac.domain.dto.request.RegisterRequest;
import com.rbac.domain.dto.response.LoginResponse;
import com.rbac.domain.dto.response.MenuResponse;
import com.rbac.domain.dto.response.UserInfoResponse;
import com.rbac.domain.entity.User;
import com.rbac.domain.entity.UserRole;
import com.rbac.infrastructure.mapper.UserRoleMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
@RequiredArgsConstructor
public class AuthServiceImpl implements AuthService {

    private final UserService userService;
    private final MenuService menuService;
    private final UserRoleMapper userRoleMapper;
    
    // 默认用户角色ID（普通用户）
    private static final Long DEFAULT_USER_ROLE_ID = 3L;

    @Override
    public LoginResponse login(LoginRequest request, String clientIp) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getUsername, request.getUsername());
        User user = userService.getOne(wrapper);

        if (user == null) {
            throw new BusinessException(BusinessErrorCode.USER_NOT_FOUND);
        }

        if (user.getStatus() == 0) {
            throw new BusinessException(BusinessErrorCode.USER_DISABLED);
        }

        if (!BCrypt.checkpw(request.getPassword(), user.getPassword())) {
            throw new BusinessException(BusinessErrorCode.LOGIN_FAILED);
        }

        StpUtil.login(user.getId());
        userService.updateLoginInfo(user.getId(), clientIp);

        LoginResponse response = new LoginResponse();
        response.setToken(StpUtil.getTokenValue());
        response.setExpiresIn(StpUtil.getTokenTimeout());

        UserInfoResponse userInfo = new UserInfoResponse();
        userInfo.setId(user.getId());
        userInfo.setUsername(user.getUsername());
        userInfo.setNickname(user.getNickname());
        userInfo.setEmail(user.getEmail());
        userInfo.setPhone(user.getPhone());
        userInfo.setAvatar(user.getAvatar());
        userInfo.setStatus(user.getStatus());
        userInfo.setLoginTime(user.getLoginTime());

        response.setUserInfo(userInfo);
        response.setPermissions(userService.getUserPermissions(user.getId()));
        response.setMenus(menuService.getUserMenus(user.getId()));

        return response;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void register(RegisterRequest request, String clientIp) {
        // 验证两次密码是否一致
        if (!request.getPassword().equals(request.getConfirmPassword())) {
            throw new BusinessException(BusinessErrorCode.PASSWORD_MISMATCH);
        }

        // 检查用户名是否已存在
        LambdaQueryWrapper<User> usernameWrapper = new LambdaQueryWrapper<>();
        usernameWrapper.eq(User::getUsername, request.getUsername());
        if (userService.count(usernameWrapper) > 0) {
            throw new BusinessException(BusinessErrorCode.USERNAME_ALREADY_EXISTS);
        }

        // 检查邮箱是否已存在
        LambdaQueryWrapper<User> emailWrapper = new LambdaQueryWrapper<>();
        emailWrapper.eq(User::getEmail, request.getEmail());
        if (userService.count(emailWrapper) > 0) {
            throw new BusinessException(BusinessErrorCode.EMAIL_ALREADY_EXISTS);
        }

        // 检查手机号是否已存在（如果提供了手机号）
        if (request.getPhone() != null && !request.getPhone().trim().isEmpty()) {
            LambdaQueryWrapper<User> phoneWrapper = new LambdaQueryWrapper<>();
            phoneWrapper.eq(User::getPhone, request.getPhone());
            if (userService.count(phoneWrapper) > 0) {
                throw new BusinessException(BusinessErrorCode.PHONE_ALREADY_EXISTS);
            }
        }

        // 创建新用户
        User user = new User();
        user.setUsername(request.getUsername());
        user.setPassword(BCrypt.hashpw(request.getPassword()));
        user.setEmail(request.getEmail());
        user.setNickname(request.getNickname() != null ? request.getNickname() : request.getUsername());
        user.setPhone(request.getPhone());
        user.setStatus(1); // 默认启用
        user.setCreatedBy(1L); // 系统用户ID
        user.setUpdatedBy(1L);

        userService.save(user);
        
        // 为新用户分配默认角色（普通用户角色，ID=3）
        UserRole userRole = new UserRole();
        userRole.setUserId(user.getId());
        userRole.setRoleId(DEFAULT_USER_ROLE_ID); // 普通用户角色ID
        userRole.setCreatedBy(1L); // 系统用户ID
        userRoleMapper.insert(userRole);
    }

    @Override
    public void logout(String token) {
        StpUtil.logout();
    }

    @Override
    public UserInfoResponse getCurrentUser() {
        Long userId = StpUtil.getLoginIdAsLong();
        User user = userService.getById(userId);

        UserInfoResponse userInfo = new UserInfoResponse();
        userInfo.setId(user.getId());
        userInfo.setUsername(user.getUsername());
        userInfo.setNickname(user.getNickname());
        userInfo.setEmail(user.getEmail());
        userInfo.setPhone(user.getPhone());
        userInfo.setAvatar(user.getAvatar());
        userInfo.setStatus(user.getStatus());
        userInfo.setLoginTime(user.getLoginTime());

        return userInfo;
    }

    @Override
    public void refreshToken() {
        StpUtil.renewTimeout(StpUtil.getTokenTimeout());
    }
}